/******************************************************
*  Copyright(c) pages.ilovezxl.top
*  FileName :link.c
*  Author : rivulet.dave
*  Description : Á´±í²Ù×÷
*  Data : 2019-04-15
******************************************************/

/*********************************************************************
 * INCLUDES
 */

#include "stdrope.h"

#include "link.h"

/*********************************************************************
 *  EXTERNAL VARIABLES
 */

/*********************************************************************
 * MACROS
 */


/*********************************************************************
 * TYPES
 */


/*********************************************************************
 * FUNCTIONS DECLARE
 */


/*********************************************************************
 *  VARIABLES
 */

/*********************************************************************
 * FUNCTIONS
 */

/**
 *   @Description: ´´½¨Á´±í
 *   @param: pstLink - Èë²Î£¬Á´±íÍ·Ö¸Õë
 *   @return £ºpstLink
 */
SLINK_S *SLINK_Init(SLINK_S *pstLink)
{
    if (NULL != pstLink)
    {
        pstLink->pstHead = NULL;
        pstLink->pstTail = NULL;
        pstLink->uiCount = 0;
    }

    return pstLink;
}

/**
 *   @Description: ×·¼ÓÁ´±í½Úµã
 *   @param: pstLink - Èë²Î£¬Á´±íÍ·Ö¸Õë
 *   @param: pstLinkNode - Èë²Î£¬Á´±íÐÂ½Úµã
 *   @return £º´íÎóÐÅÏ¢
 */
int32_t SLINK_Append(SLINK_S *pstLink, SLINK_NODE_S *pstLinkNode)
{
    if (NULL == pstLinkNode)
    {
        return _ERR;
    }

    pstLinkNode->pNext = NULL;
    if (true == SLINK_IsEmpty(pstLink))
    {
        pstLink->pstHead = pstLinkNode;
        pstLink->pstTail = pstLinkNode;
    }
    else
    {
        pstLink->pstTail->pNext = pstLinkNode;
        pstLink->pstTail        = pstLinkNode;
    }
    
    pstLink->uiCount++;
    return _OK;
}

/**
 *   @Description: ÔÚÁ´±íÇ°²åÈëÐÂ½Úµã
 *   @param: pstLink - Èë²Î£¬Á´±íÍ·Ö¸Õë
 *   @param: pstLinkNode - Èë²Î£¬Á´±íÐÂ½Úµã
 *   @return £º´íÎóÐÅÏ¢
 */
int32_t SLINK_InsertFront(SLINK_S *pstLink, SLINK_NODE_S *pstLinkNode)
{
    if (NULL == pstLink || NULL == pstLinkNode)
    {
        return _ERR;
    }

    pstLinkNode->pNext = NULL;
    if (true == SLINK_IsEmpty(pstLink))
    {
        pstLink->pstHead = pstLinkNode;
        pstLink->pstTail = pstLinkNode;
    }
    else
    {
        pstLinkNode->pNext = pstLink->pstHead;
        pstLink->pstHead = pstLinkNode;
    }
    
    pstLink->uiCount++;
    return _OK;
}

/**
 *   @Description: »ñÁËÁ´±í½Úµã
 *   @param: pstLink - Èë²Î£¬Á´±íÍ·Ö¸Õë
 *   @return £ºÁ´±í½ÚµãµØÖ·
 */
SLINK_NODE_S *SLINK_Peek(SLINK_S *pstLink)
{
    SLINK_NODE_S *pstNode;

    if (true == SLINK_IsEmpty(pstLink))
    {
        return NULL;
    }

    pstNode = pstLink->pstHead;
    pstLink->pstHead = pstLink->pstHead->pNext;
    if (pstLink->pstHead == NULL)
    {
        pstLink->pstTail = NULL;
    }
    
    return pstNode;
}

/**
 *   @Description: É¾³ýÁ´±í½Úµã
 *   @param *pstLink - Èë²Î£¬Á´±í
 *   @param *pstLinkNode - ÒªÉ¾³ýµÄÁ´±í½Úµã
 *   @return £º_OK / _ERR
 */
int32_t SLINK_DeleteNode(SLINK_S *pstLink, SLINK_NODE_S *pstLinkNode)
{
    SLINK_NODE_S *pstTempNode = NULL;

    if (true == SLINK_IsEmpty(pstLink))
    {
        return _ERR;
    }

    pstTempNode = pstLink->pstHead;
    if (pstTempNode == pstLinkNode)
    {
        pstLink->pstHead = pstTempNode->pNext;
        /* ÈôÍ·ÎªNULL£¬ÔòÁ´±íÒÑ¿Õ£¬½«Î²Ò²È¥µô */
        if (NULL == pstLink->pstHead)
        {
            pstLink->pstTail = NULL;
        }
        pstLink->uiCount = 0;
        return _OK;
    }

    while (NULL != pstTempNode->pNext && pstTempNode->pNext != pstLinkNode)
    {
        pstTempNode = pstTempNode->pNext;
    }

    if (NULL != pstTempNode->pNext)
    {
        pstTempNode->pNext = pstTempNode->pNext->pNext;
        /* ÈôÉ¾³ýµÄÊÇÎ²£¬ÔòÖØÐÂÉèÖÃÎ² */
        if (pstLink->pstTail == pstLinkNode)
        {
            pstLink->pstTail = pstTempNode;
        }
        pstLink->uiCount--;
        return _OK;
    }
    /* Ã»ÕÒµ½ÒªÉ¾³ýµÄ½Úµã */
    else
    {
        return _ERR;
    }
}

/**
 *   @Description: ÅÐ¶ÏÁ´±íÊÇ·ñÎª¿Õ
 *   @param *pstLink - Èë²Î£¬Á´±í
 *   @return £º_TRUE / _FALSE
 */
bool SLINK_IsEmpty(SLINK_S *pstLink)
{
    if (NULL == pstLink->pstHead)
    {
        return true;
    }
    else
    {
        return false;
    }
}

